package com.plian.system.service.transfer.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.plian.Tools.CollectionUtil;
import com.plian.Tools.StringPool;
import com.plian.Tools.TokenUtil;
import com.plian.system.constant.im.InvestmentConstant;
import com.plian.system.constant.sys.FormTypeConstant;
import com.plian.system.entity.im.*;
import com.plian.system.entity.pm.property.PropertyBasics;
import com.plian.system.entity.sys.Org;
import com.plian.system.model.R;
import com.plian.system.service.im.*;
import com.plian.system.service.pm.property.IPropertyBasicsService;
import com.plian.system.service.sys.code.IFormCodeService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.service.transfer.IInvestmentTransferService;
import com.plian.system.service.transfer.ITransferFlowService;
import com.plian.system.vo.im.*;
import com.plian.system.wrapper.im.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.plian.system.constant.sys.FormStatusConstant.*;

@Slf4j
@Service
@AllArgsConstructor
public class InvestmentTransferServiceImpl implements IInvestmentTransferService {

    private IProjectInfoService projectInfoService;

    private ProjectInfoWrapper projectInfoWrapper;

    private IFundProjectInfoService fundProjectInfoService;

    private FundProjectInfoWrapper fundProjectInfoWrapper;

    private IOrgService orgService;

    private IBaseInvestmentPlanService baseInvestmentPlanService;

    private IFormCodeService formCodeService;

    private BaseInvestmentPlanWrapper baseInvestmentPlanWrapper;

    private IFixedInvestmentPlanService fixedInvestmentPlanService;

    private IStakeInvestmentPlanService stakeInvestmentPlanService;

    private StakeInvestmentPlanWrapper stakeInvestmentPlanWrapper;

    private FixedInvestmentPlanWrapper fixedInvestmentPlanWrapper;

    private IBaseInvestmentExecutionService baseInvestmentExecutionService;

    private IEffectiveInvestmentService effectiveInvestmentService;

    private IExecutionProjectSituationService executionProjectSituationService;

    private BaseInvestmentExecutionWrapper baseInvestmentExecutionWrapper;

    private EffectiveInvestmentWrapper effectiveInvestmentWrapper;

    private ExecutionProjectSituationWrapper executionProjectSituationWrapper;

    private IFundProjectExecutionService fundProjectExecutionService;

    private FundProjectExecutionWrapper fundProjectExecutionWrapper;

    private IFundProjectService fundProjectService;

    private FundProjectWrapper fundProjectWrapper;

    private IFundInvestedProjectService fundInvestedProjectService;

    private FundInvestedProjectWrapper fundInvestedProjectWrapper;

    private ITransferFlowService transferFlowService;

    private IPropertyBasicsService propertyBasicsService;

    private IFundProjectAmountDetailService fundProjectAmountDetailService;

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public R submitProjectList(List<ProjectInfoVO> projectInfoVOS) {
        if (CollectionUtil.isEmpty(projectInfoVOS)){
            return R.success();
        }

        String tokenOrgId = TokenUtil.getTokenOrgId();
        String tokenUserId = TokenUtil.getTokenUserId();
        List<ProjectInfo> allOldList = projectInfoService.list(new LambdaQueryWrapper<ProjectInfo>()
                .eq(ProjectInfo::getCreateCompanyId, tokenOrgId));
        Map<String, ProjectInfo> projectNameMap = allOldList.stream()
                .collect(Collectors.toMap(ProjectInfo::getProjectName, projectInfo -> projectInfo));

        List<ProjectInfo> projectInfos = new ArrayList<>();
        for (ProjectInfoVO projectInfoVO : projectInfoVOS){
            if (projectNameMap.containsKey(projectInfoVO.getProjectName())){
                projectInfoVO.setId(projectNameMap.get(projectInfoVO.getProjectName()).getId());
            }
            projectInfoVO.setDataSource(tokenUserId);
            projectInfoVO.setStatus(UNREVIEWED);
            projectInfoVO.setIsDeleted(0);
            projectInfos.add(projectInfoWrapper.voToEntity(projectInfoVO));
        }

        projectInfoService.saveList(projectInfos);
        return R.success();
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public R submitFundProjectList(List<FundProjectInfoVO> fundProjectInfoVOS) {
        if (CollectionUtil.isEmpty(fundProjectInfoVOS)){
            return R.success();
        }

        String tokenOrgId = TokenUtil.getTokenOrgId();
        String tokenUserId = TokenUtil.getTokenUserId();
        List<FundProjectInfo> allOldList = fundProjectInfoService.list(new LambdaQueryWrapper<FundProjectInfo>()
                .eq(FundProjectInfo::getCreateCompanyId, tokenOrgId));
        Map<String, FundProjectInfo> projectNameMap = allOldList.stream()
                .collect(Collectors.toMap(FundProjectInfo::getFundName, projectInfo -> projectInfo));
        List<PropertyBasics> propertyBasicsList = propertyBasicsService
                .list(new LambdaQueryWrapper<PropertyBasics>()
                        .ne(PropertyBasics::getStatus, 4)
                        .eq(PropertyBasics::getCompetentOrganization, TokenUtil.getCompetentOrganization()));

        Map<String, PropertyBasics> orgNameMap = propertyBasicsList.stream().collect(Collectors.toMap(PropertyBasics::getOrgName, propertyBasics -> propertyBasics));

        List<String> messages = new ArrayList<>();
        for (FundProjectInfoVO fundProjectInfoVO : fundProjectInfoVOS){
            if (!orgNameMap.containsKey(fundProjectInfoVO.getCompanyName())){
                messages.add(fundProjectInfoVO.getFundName() + StringPool.UNDERSCORE + fundProjectInfoVO.getCompanyName());
                continue;
            }

            if (projectNameMap.containsKey(fundProjectInfoVO.getFundName())){
                fundProjectInfoVO.setId(projectNameMap.get(fundProjectInfoVO.getFundName()).getId());
            }
            fundProjectInfoVO.setCompanyId(orgNameMap.get(fundProjectInfoVO.getCompanyName()).getId());
            fundProjectInfoVO.setDataSource(tokenUserId);
            fundProjectInfoVO.setStatus(UNREVIEWED);
            fundProjectInfoVO.setIsDeleted(0);
            FundProjectInfo fundProjectInfo = fundProjectInfoWrapper.voToEntity(fundProjectInfoVO);
            fundProjectInfoService.saveOrUpdate(fundProjectInfo);
            if (fundProjectInfo.getId() != null){
                fundProjectAmountDetailService.removeByBaseId(fundProjectInfo.getId());
            }
            if (CollectionUtil.isNotEmpty(fundProjectInfoVO.getGpDetailList())){
                for (int i = 0; i < fundProjectInfoVO.getGpDetailList().size(); i++){
                    FundProjectAmountDetail amountDetail = fundProjectInfoVO.getGpDetailList().get(i);
                    amountDetail.setOrderNumber(i + 1);
                    amountDetail.setAmountType(InvestmentConstant.GP_AMOUNT_DETAIL_TYPE);
                    amountDetail.setFundProjectId(fundProjectInfo.getId());
                    amountDetail.setId(null);
                }
                fundProjectAmountDetailService.saveBatch(fundProjectInfoVO.getGpDetailList());
            }
            if (CollectionUtil.isNotEmpty(fundProjectInfoVO.getLpDetailList())){
                for (int i = 0; i < fundProjectInfoVO.getLpDetailList().size(); i++){
                    FundProjectAmountDetail amountDetail = fundProjectInfoVO.getLpDetailList().get(i);
                    amountDetail.setOrderNumber(i + 1);
                    amountDetail.setAmountType(InvestmentConstant.LP_AMOUNT_DETAIL_TYPE);
                    amountDetail.setFundProjectId(fundProjectInfo.getId());
                    amountDetail.setId(null);
                }
                fundProjectAmountDetailService.saveBatch(fundProjectInfoVO.getLpDetailList());
            }
        }

        if (CollectionUtil.isNotEmpty(messages)){
            return R.data(messages.stream().collect(Collectors.joining(StringPool.COMMA)) + "单位不存在");
        }
        return R.success();
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public R submitPlanList(List<BaseInvestmentPlanVO> baseInvestmentPlanVOS) {
        if (CollectionUtil.isEmpty(baseInvestmentPlanVOS)){
            return R.success();
        }
        String tokenOrgId = TokenUtil.getTokenOrgId();
        String tokenUserId = TokenUtil.getTokenUserId();
        List<BaseInvestmentPlan> baseInvestmentPlanList = baseInvestmentPlanService
                .list(new LambdaQueryWrapper<BaseInvestmentPlan>().eq(BaseInvestmentPlan::getDataSource, tokenUserId));
        Map<String, BaseInvestmentPlan> dataSourceIdPlanMap = baseInvestmentPlanList.stream()
                .collect(Collectors.toMap(BaseInvestmentPlan::getDataSourceId, plan -> plan));
        List<ProjectInfo> projectInfoList = projectInfoService
                .list(new LambdaQueryWrapper<ProjectInfo>().eq(ProjectInfo::getDataSource, tokenUserId));
        Map<String, ProjectInfo> dataSourceIdProjectInfoMap = projectInfoList.stream()
                .collect(Collectors.toMap(ProjectInfo::getDataSourceId, projectInfo -> projectInfo));

        List<Long> updatePlanIds = new ArrayList<>();
        List<String> messages = new ArrayList<>();
        List<FixedInvestmentPlan> fixedInvestmentPlans = new ArrayList<>();
        List<StakeInvestmentPlan> stakeInvestmentPlans = new ArrayList<>();
        List<String> submitIds = new ArrayList<>();
        for (BaseInvestmentPlanVO baseInvestmentPlanVO : baseInvestmentPlanVOS){
            if (dataSourceIdPlanMap.containsKey(baseInvestmentPlanVO.getDataSourceId())){
                BaseInvestmentPlan baseInvestmentPlan = dataSourceIdPlanMap.get(baseInvestmentPlanVO.getDataSourceId());
                int status = baseInvestmentPlan.getStatus();
                if (status != UNREVIEWED && status != REJECT && status != STASH){
                    messages.add(baseInvestmentPlanVO.getFilingYear() + "年,dataSourceId="
                            + baseInvestmentPlanVO.getDataSourceId() + " 该数据审批中或已审核,");
                    continue;
                }
                updatePlanIds.add(baseInvestmentPlan.getId());
                baseInvestmentPlanVO.setId(baseInvestmentPlan.getId());
                baseInvestmentPlanVO.setCode(baseInvestmentPlan.getCode());
                baseInvestmentPlanVO.setStatus(baseInvestmentPlan.getStatus());
            }else {
                baseInvestmentPlanVO.setStatus(UNREVIEWED);
                baseInvestmentPlanVO.setCode(formCodeService.getCode(FormTypeConstant.IM_BASE_INVESTMENT_PLAN_FORM));
            }
            baseInvestmentPlanVO.setFilingUnitId(tokenOrgId);
            baseInvestmentPlanVO.setFormType(String.valueOf(FormTypeConstant.IM_BASE_INVESTMENT_PLAN_FORM));
            baseInvestmentPlanVO.setDataSource(tokenUserId);
            baseInvestmentPlanVO.setIsDeleted(0);

            BaseInvestmentPlan baseInvestmentPlan =  baseInvestmentPlanWrapper.voToEntity(baseInvestmentPlanVO);
            baseInvestmentPlanService.saveOrUpdate(baseInvestmentPlan);
            submitIds.add(String.valueOf(baseInvestmentPlan.getId()));

            if (CollectionUtil.isNotEmpty(baseInvestmentPlanVO.getFixedInvestmentPlanVOS())){
                for (FixedInvestmentPlanVO fixedInvestmentPlanVO : baseInvestmentPlanVO.getFixedInvestmentPlanVOS()){
                    if (!dataSourceIdProjectInfoMap.containsKey(fixedInvestmentPlanVO.getProjectDataSourceId())){
                        messages.add(baseInvestmentPlanVO.getFilingYear() + "年,dataSourceId="
                                + baseInvestmentPlanVO.getDataSourceId() + ",项目名称："
                                + fixedInvestmentPlanVO.getProjectName() + ", projectDataSourceId="
                                + fixedInvestmentPlanVO.getProjectDataSourceId() + "不存在");
                        continue;
                    }
                    fixedInvestmentPlanVO.setBaseInvestmentPlanId(baseInvestmentPlan.getId());
                    fixedInvestmentPlanVO.setProjectId(dataSourceIdProjectInfoMap.get(fixedInvestmentPlanVO.getProjectDataSourceId()).getId());
                    fixedInvestmentPlans.add(fixedInvestmentPlanWrapper.voToEntity(fixedInvestmentPlanVO));
                }
                baseInvestmentPlanVO.setFixedInvestmentPlans(fixedInvestmentPlans);
            }

            if (CollectionUtil.isNotEmpty(baseInvestmentPlanVO.getStakeInvestmentPlanVOS())){
                for (StakeInvestmentPlanVO stakeInvestmentPlanVO : baseInvestmentPlanVO.getStakeInvestmentPlanVOS()){
                    if (!dataSourceIdProjectInfoMap.containsKey(stakeInvestmentPlanVO.getProjectDataSourceId())){
                        messages.add(baseInvestmentPlanVO.getFilingYear() + "年,dataSourceId="
                                + baseInvestmentPlanVO.getDataSourceId() + ",项目名称："
                                + stakeInvestmentPlanVO.getProjectName() + ", projectDataSourceId="
                                + stakeInvestmentPlanVO.getProjectDataSourceId() + "不存在");
                        continue;
                    }
                    stakeInvestmentPlanVO.setBaseInvestmentPlanId(baseInvestmentPlan.getId());
                    stakeInvestmentPlanVO.setProjectId(dataSourceIdProjectInfoMap.get(stakeInvestmentPlanVO.getProjectDataSourceId()).getId());
                    stakeInvestmentPlans.add(stakeInvestmentPlanWrapper.voToEntity(stakeInvestmentPlanVO));
                }
                baseInvestmentPlanVO.setStakeInvestmentPlans(stakeInvestmentPlans);
            }
        }

        if (CollectionUtil.isNotEmpty(updatePlanIds)){
            fixedInvestmentPlanService.remove(new LambdaQueryWrapper<FixedInvestmentPlan>().in(FixedInvestmentPlan::getBaseInvestmentPlanId, updatePlanIds));
            stakeInvestmentPlanService.remove(new LambdaQueryWrapper<StakeInvestmentPlan>().in(StakeInvestmentPlan::getBaseInvestmentPlanId, updatePlanIds));
        }

        if (CollectionUtil.isNotEmpty(fixedInvestmentPlans)){
            fixedInvestmentPlanService.saveList(fixedInvestmentPlans);
        }
        if (CollectionUtil.isNotEmpty(stakeInvestmentPlans)){
            stakeInvestmentPlanService.saveList(stakeInvestmentPlans);
        }

//        if (CollectionUtil.isNotEmpty(submitIds)){
//            transferFlowService.submit(submitIds, FormTypeConstant.IM_BASE_INVESTMENT_PLAN_FORM);
//        }

        if (CollectionUtil.isNotEmpty(messages)){
            return R.data(messages.stream().collect(Collectors.joining(StringPool.COMMA)));
        }
        return R.success();
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public R submitExecutionList(List<BaseInvestmentExecutionVO> baseInvestmentExecutionVOS) {
        if (CollectionUtil.isEmpty(baseInvestmentExecutionVOS)){
            return R.success();
        }
        String tokenOrgId = TokenUtil.getTokenOrgId();
        String tokenUserId = TokenUtil.getTokenUserId();

        List<BaseInvestmentExecution> baseInvestmentExecutions = baseInvestmentExecutionService
                .list(new LambdaQueryWrapper<BaseInvestmentExecution>().eq(BaseInvestmentExecution::getCreateCompanyId, tokenOrgId));
        Map<String, BaseInvestmentExecution> monthExeMap = baseInvestmentExecutions
                .stream().collect(Collectors.toMap(BaseInvestmentExecution::getFilingMonth, execution -> execution));
        List<ProjectInfo> projectInfoList = projectInfoService
                .list(new LambdaQueryWrapper<ProjectInfo>().eq(ProjectInfo::getDataSource, tokenUserId));
        Map<String, ProjectInfo> dataSourceIdProjectInfoMap = projectInfoList.stream()
                .collect(Collectors.toMap(ProjectInfo::getDataSourceId, projectInfo -> projectInfo));

        List<Long> updateEffectiveIds = new ArrayList<>();
        List<String> messages = new ArrayList<>();
        List<ExecutionProjectSituation> executionProjectSituations = new ArrayList<>();
        List<String> submitIds = new ArrayList<>();
        for (BaseInvestmentExecutionVO baseInvestmentExecutionVO : baseInvestmentExecutionVOS){
            if (monthExeMap.containsKey(baseInvestmentExecutionVO.getFilingMonth())){
                BaseInvestmentExecution baseInvestmentExecution = monthExeMap.get(baseInvestmentExecutionVO.getFilingMonth());
                int status = baseInvestmentExecution.getStatus();
                if (status != UNREVIEWED && status != REJECT && status != STASH){
                    messages.add(baseInvestmentExecution.getFilingMonth() + ",dataSourceId="
                            + baseInvestmentExecution.getDataSourceId() + " 该数据审批中或已审核,");
                    continue;
                }
                baseInvestmentExecutionVO.setId(baseInvestmentExecution.getId());
                baseInvestmentExecutionVO.setCode(baseInvestmentExecution.getCode());
                baseInvestmentExecutionVO.setStatus(baseInvestmentExecution.getStatus());
            }else {
                baseInvestmentExecutionVO.setStatus(UNREVIEWED);
                baseInvestmentExecutionVO.setCode(formCodeService.getCode(FormTypeConstant.IM_BASE_INVESTMENT_EXECUTION_FORM));
            }

            baseInvestmentExecutionVO.setFilingUnitId(tokenOrgId);
            baseInvestmentExecutionVO.setFormType(String.valueOf(FormTypeConstant.IM_BASE_INVESTMENT_EXECUTION_FORM));
            baseInvestmentExecutionVO.setDataSource(tokenUserId);
            baseInvestmentExecutionVO.setIsDeleted(0);

            BaseInvestmentExecution baseInvestmentExecution =  baseInvestmentExecutionWrapper.voToEntity(baseInvestmentExecutionVO);
            baseInvestmentExecutionService.saveOrUpdate(baseInvestmentExecution);
            submitIds.add(String.valueOf(baseInvestmentExecution.getId()));

            if (baseInvestmentExecutionVO.getEffectiveInvestmentVO() != null){
                EffectiveInvestmentVO effectiveInvestmentVO = baseInvestmentExecutionVO.getEffectiveInvestmentVO();
                EffectiveInvestment old = effectiveInvestmentService.getOne(new LambdaQueryWrapper<EffectiveInvestment>()
                        .eq(EffectiveInvestment::getBaseInvestmentExecutionId, baseInvestmentExecution.getId()));
                if (old != null){
                    updateEffectiveIds.add(old.getId());
                    effectiveInvestmentVO.setId(old.getId());
                    effectiveInvestmentVO.setBaseInvestmentExecutionId(baseInvestmentExecution.getId());
                }else {
                    effectiveInvestmentVO.setBaseInvestmentExecutionId(baseInvestmentExecution.getId());
                }
                EffectiveInvestment effectiveInvestment = effectiveInvestmentWrapper.voToEntity(effectiveInvestmentVO);
                effectiveInvestmentService.saveOrUpdate(effectiveInvestment);

                if (CollectionUtil.isNotEmpty(effectiveInvestmentVO.getFixedProjectSituationVOS())){
                    for (ExecutionProjectSituationVO executionProjectSituationVO : effectiveInvestmentVO.getFixedProjectSituationVOS()){
                        if (!dataSourceIdProjectInfoMap.containsKey(executionProjectSituationVO.getProjectDataSourceId())){
                            messages.add(baseInvestmentExecutionVO.getFilingMonth() + ",dataSourceId="
                                    + baseInvestmentExecutionVO.getDataSourceId() + ",项目名称："
                                    + executionProjectSituationVO.getProjectName() + ", projectDataSourceId="
                                    + executionProjectSituationVO.getProjectDataSourceId() + "不存在");
                            continue;
                        }
                        executionProjectSituationVO.setProjectType(2);
                        executionProjectSituationVO.setEffectiveInvestmentId(effectiveInvestment.getId());
                        executionProjectSituationVO.setProjectId(dataSourceIdProjectInfoMap.get(executionProjectSituationVO.getProjectDataSourceId()).getId());
                        executionProjectSituations.add(executionProjectSituationWrapper.voToEntity(executionProjectSituationVO));
                    }
                }

                if (CollectionUtil.isNotEmpty(effectiveInvestmentVO.getStakeProjectSituationVOS())){
                    for (ExecutionProjectSituationVO executionProjectSituationVO : effectiveInvestmentVO.getStakeProjectSituationVOS()){
                        if (!dataSourceIdProjectInfoMap.containsKey(executionProjectSituationVO.getProjectDataSourceId())){
                            messages.add(baseInvestmentExecutionVO.getFilingMonth() + ",dataSourceId="
                                    + baseInvestmentExecutionVO.getDataSourceId() + ",项目名称："
                                    + executionProjectSituationVO.getProjectName() + ", projectDataSourceId="
                                    + executionProjectSituationVO.getProjectDataSourceId() + "不存在");
                            continue;
                        }
                        executionProjectSituationVO.setProjectType(1);
                        executionProjectSituationVO.setEffectiveInvestmentId(effectiveInvestment.getId());
                        executionProjectSituationVO.setProjectId(dataSourceIdProjectInfoMap.get(executionProjectSituationVO.getProjectDataSourceId()).getId());
                        executionProjectSituations.add(executionProjectSituationWrapper.voToEntity(executionProjectSituationVO));
                    }
                }
            }
        }

        if (CollectionUtil.isNotEmpty(updateEffectiveIds)){
            executionProjectSituationService.remove(new LambdaQueryWrapper<ExecutionProjectSituation>().in(ExecutionProjectSituation::getEffectiveInvestmentId, updateEffectiveIds));
        }
        if (CollectionUtil.isNotEmpty(executionProjectSituations)){
            executionProjectSituationService.saveList(executionProjectSituations);
        }
//        if (CollectionUtil.isNotEmpty(submitIds)){
//            transferFlowService.submit(submitIds, FormTypeConstant.IM_BASE_INVESTMENT_EXECUTION_FORM);
//        }

        if (CollectionUtil.isNotEmpty(messages)){
            return R.data(messages.stream().collect(Collectors.joining(StringPool.COMMA)));
        }
        return R.success();
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public R submitFundExecutionList(List<FundProjectExecutionVO> fundProjectExecutionVOS) {
        if (CollectionUtil.isEmpty(fundProjectExecutionVOS)){
            return R.success();
        }
        String tokenOrgId = TokenUtil.getTokenOrgId();
        String tokenUserId = TokenUtil.getTokenUserId();

        List<FundProjectExecution> baseInvestmentExecutions = fundProjectExecutionService
                .list(new LambdaQueryWrapper<FundProjectExecution>().eq(FundProjectExecution::getCreateCompanyId, tokenOrgId));
        Map<String, FundProjectExecution> monthExeMap = baseInvestmentExecutions
                .stream().collect(Collectors.toMap(FundProjectExecution::getFilingMonth, execution -> execution));
        List<FundProjectInfo> projectInfoList = fundProjectInfoService
                .list(new LambdaQueryWrapper<FundProjectInfo>().eq(FundProjectInfo::getDataSource, tokenUserId));
        Map<String, FundProjectInfo> dataSourceIdFundProjectInfoMap = projectInfoList.stream()
                .collect(Collectors.toMap(FundProjectInfo::getDataSourceId, projectInfo -> projectInfo));
        List<Org> allOrg = orgService.getAllChild(tokenOrgId);
        Map<String, Org> orgNameMap = allOrg.stream().collect(Collectors.toMap(Org::getName, org -> org));

        List<Long> updateExecutionIds = new ArrayList<>();
        List<String> messages = new ArrayList<>();
        List<FundProject> fundProjects = new ArrayList<>();
        List<String> submitIds = new ArrayList<>();
        for (FundProjectExecutionVO fundProjectExecutionVO : fundProjectExecutionVOS){
            if (monthExeMap.containsKey(fundProjectExecutionVO.getFilingMonth())){
                FundProjectExecution fundProjectExecution = monthExeMap.get(fundProjectExecutionVO.getFilingMonth());
                int status = fundProjectExecution.getStatus();
                if (status != UNREVIEWED && status != REJECT && status != STASH){
                    messages.add(fundProjectExecution.getFilingMonth() + ",dataSourceId="
                            + fundProjectExecution.getDataSourceId() + " 该数据审批中或已审核,");
                    continue;
                }
                fundProjectExecutionVO.setId(fundProjectExecution.getId());
                fundProjectExecutionVO.setCode(fundProjectExecution.getCode());
                fundProjectExecutionVO.setStatus(fundProjectExecution.getStatus());
                updateExecutionIds.add(fundProjectExecution.getId());
            }else {
                fundProjectExecutionVO.setStatus(UNREVIEWED);
                fundProjectExecutionVO.setCode(formCodeService.getCode(FormTypeConstant.IM_FUNDPROJECT_EXECUTION));
            }

            fundProjectExecutionVO.setFilingUnitId(tokenOrgId);
            fundProjectExecutionVO.setFormType(String.valueOf(FormTypeConstant.IM_FUNDPROJECT_EXECUTION));
            fundProjectExecutionVO.setDataSource(tokenUserId);
            fundProjectExecutionVO.setIsDeleted(0);

            FundProjectExecution fundProjectExecution =  fundProjectExecutionWrapper.voToEntity(fundProjectExecutionVO);
            fundProjectExecutionService.saveOrUpdate(fundProjectExecution);
            submitIds.add(String.valueOf(fundProjectExecution.getId()));

            if (CollectionUtil.isNotEmpty(fundProjectExecutionVO.getFundProjectVOS())){
                for (FundProjectVO fundProjectVO : fundProjectExecutionVO.getFundProjectVOS()){
                    if (!dataSourceIdFundProjectInfoMap.containsKey(fundProjectVO.getFundProjectDataSourceId())){
                        messages.add(fundProjectExecutionVO.getFilingMonth() + ",dataSourceId="
                                + fundProjectExecutionVO.getDataSourceId() + ",基金项目名称："
                                + fundProjectVO.getFundName() + ", fundProjectDataSourceId="
                                + fundProjectVO.getFundProjectDataSourceId() + "不存在");
                        continue;
                    }
                    fundProjectVO.setCompanyId(orgNameMap.get(fundProjectVO.getCompanyName()).getId());
                    fundProjectVO.setFundProjectExecutionId(fundProjectExecution.getId());
                    fundProjectVO.setFundProjectInfoId(dataSourceIdFundProjectInfoMap.get(fundProjectVO.getFundProjectDataSourceId()).getId());
                    FundProject fundProject = fundProjectWrapper.voToEntity(fundProjectVO);
                    fundProjects.add(fundProject);

                    if (CollectionUtil.isNotEmpty(fundProjectVO.getFundInvestedProjectVOS())){
                        fundProject.setFundInvestedProjects(fundInvestedProjectWrapper.voToEntity(fundProjectVO.getFundInvestedProjectVOS()));
                    }
                }
            }
        }

        if (CollectionUtil.isNotEmpty(updateExecutionIds)){
            List<FundProject> removeFundProjectList = fundProjectService.list(new LambdaQueryWrapper<FundProject>().in(FundProject::getFundProjectExecutionId, updateExecutionIds));
            if (CollectionUtil.isNotEmpty(removeFundProjectList)){
                List<Long> fundProjectIds = removeFundProjectList.stream().map(FundProject::getId).collect(Collectors.toList());
                fundInvestedProjectService.remove(new LambdaQueryWrapper<FundInvestedProject>()
                        .in(FundInvestedProject::getFundProjectId, fundProjectIds));
                fundProjectAmountDetailService.remove(new LambdaQueryWrapper<FundProjectAmountDetail>()
                        .in(FundProjectAmountDetail::getFundProjectId, fundProjectIds));
                fundProjectService.remove(new LambdaQueryWrapper<FundProject>().in(FundProject::getFundProjectExecutionId, updateExecutionIds));
            }
        }
        if (CollectionUtil.isNotEmpty(fundProjects)){
            fundProjectService.saveList(fundProjects);
            List<FundInvestedProject> fundInvestedProjects = new ArrayList<>();
            List<FundProjectAmountDetail> fundProjectAmountDetails = new ArrayList<>();
            for (FundProject fundProject : fundProjects){
                if (CollectionUtil.isNotEmpty(fundProject.getFundInvestedProjects())){
                    for (FundInvestedProject fundInvestedProject : fundProject.getFundInvestedProjects()){
                        fundInvestedProject.setFundProjectId(fundProject.getId());
                        fundInvestedProjects.add(fundInvestedProject);
                    }
                }
                if (CollectionUtil.isNotEmpty(fundProject.getGpDetailList())){
                    for (int i = 0; i < fundProject.getGpDetailList().size(); i++){
                        FundProjectAmountDetail amountDetail = fundProject.getGpDetailList().get(i);
                        amountDetail.setOrderNumber(i + 1);
                        amountDetail.setAmountType(InvestmentConstant.GP_AMOUNT_DETAIL_TYPE);
                        amountDetail.setFundProjectId(fundProject.getId());
                        amountDetail.setId(null);
                    }
                    fundProjectAmountDetails.addAll(fundProject.getGpDetailList());

                }
                if (CollectionUtil.isNotEmpty(fundProject.getLpDetailList())){
                    for (int i = 0; i < fundProject.getLpDetailList().size(); i++){
                        FundProjectAmountDetail amountDetail = fundProject.getLpDetailList().get(i);
                        amountDetail.setOrderNumber(i + 1);
                        amountDetail.setAmountType(InvestmentConstant.LP_AMOUNT_DETAIL_TYPE);
                        amountDetail.setFundProjectId(fundProject.getId());
                        amountDetail.setId(null);
                    }
                    fundProjectAmountDetails.addAll(fundProject.getLpDetailList());
                }
            }
            if (CollectionUtil.isNotEmpty(fundInvestedProjects)){
                fundInvestedProjectService.saveList(fundInvestedProjects);
            }
            if (CollectionUtil.isNotEmpty(fundProjectAmountDetails)){
                fundProjectAmountDetailService.saveBatch(fundProjectAmountDetails);
            }
        }
//        if (CollectionUtil.isNotEmpty(submitIds)){
//            transferFlowService.submit(submitIds, FormTypeConstant.IM_FUNDPROJECT_EXECUTION);
//        }

        if (CollectionUtil.isNotEmpty(messages)){
            return R.data(messages.stream().collect(Collectors.joining(StringPool.COMMA)));
        }
        return R.success();
    }
}
